package com.tengju.bff.interfaces.manage.crm.dealer.facade;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.tengju.bff.interfaces.shared.ColumnVO;
import com.tengju.bff.interfaces.shared.TableAssembler;
import com.tengju.bff.interfaces.shared.TableVO;
import com.tengju.data.domain.model.analysis.MetaHolder;
import com.tengju.data.domain.model.analysis.Row;
import com.tengju.data.domain.model.user.ReportDealerInfoRepository;
import com.tengju.data.domain.shared.CastUtil;
import com.tengju.data.domain.shared.Month;
import com.tengju.user.domain.model.sign.ReportMonthSignStepEnum;
import com.tengju.user.domain.model.sign.StarSignStepEnum;
import com.tengju.user.domain.model.user.StarLevelEnum;
import com.tengju.user.domain.model.user.UserIdCode;
import com.tengju.user.domain.model.user.UserInfo;
import com.tengju.user.domain.model.user.UserInfoRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
@Slf4j
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
public class ReportDealerInfoFacade {

    private final ReportDealerInfoRepository reportDealerInfoRepository;
    private final MetaHolder metaHolder;
    private final UserInfoRepository userInfoRepository;

    /**
     * 本月新增经销商数
     */
    public TableVO getMonthPullDealers(List<UserIdCode> genSecIdCodes) {
        Integer offset = 0;
        Integer limit = 100000;

        TableVO tableVO = new TableVO();
        TableAssembler.buildColumns(tableVO,metaHolder.listMeta("dealer_detail_with_month_pull").values());
        tableVO.addColumn(null,ColumnVO.of("id_code","用户id",false))
                .addColumn("nick_name",ColumnVO.of("star_level_desc","服务商等级",false));

        // 当前月
        Month curMonth = new Month(LocalDate.now());

        if (CollectionUtils.isEmpty(genSecIdCodes)) {
            return tableVO;
        }
        List<Long> secIdCodeList = genSecIdCodes.stream()
                .map(UserIdCode::getValue).collect(Collectors.toList());


        if (curMonth.getStartDate().equals(LocalDate.now())) {
            curMonth = curMonth.preMonth();
        }
        List<Row> rowList =
                reportDealerInfoRepository.getCurrentMonthNewIncrease(curMonth,secIdCodeList,offset,limit);

        if (CollectionUtils.isEmpty(rowList)) {
            return tableVO;
        }
        // 用户、用户上级
        List<String> keyList = List.of(
                "id_code",
                "sup_id_code"
        );
        Map<Long, UserInfo> userInfoMap = this.getUserInfosToMap(rowList,keyList);

        TableAssembler.buildData(
                tableVO,
                rowList,
                metaHolder.listMeta("dealer_detail_with_month_pull").values(),
                List.of("id_code","star_level"));

        tableVO.resolveRow(data -> {
            //转换星级等级描述
            int level = CastUtil.castInt(data.get("star_level"));
            StarLevelEnum starLevelEnum = StarLevelEnum.parseByCode(level);
            data.put("star_level_desc",starLevelEnum.getDesc());

            //昵称
            String nickName = CastUtil.castString(data.get("nick_name"));
            long idCode = CastUtil.castLong(data.get("id_code"));
            UserInfo userInfo = userInfoMap.get(idCode);
            if (StringUtils.isBlank(nickName) && userInfo != null) {
                data.put("nick_name",userInfo.getBackNickName());
            }

            //上级昵称
            String supNickName = CastUtil.castString(data.get("sup_nick_name"));
            if (StringUtils.isBlank(supNickName)) {
                long supIdCode = CastUtil.castLong(data.get("sup_id_code"));
                UserInfo supUserInfo = userInfoMap.get(supIdCode);
                if (supUserInfo != null) {
                    data.put("sup_nick_name",supUserInfo.getBackNickName());
                }
            }
        });
        return tableVO;
    }

    /**
     * 签约中服务商数
     */
    public TableVO getStarSigningDealers(List<UserIdCode> genSecIdCodes) {
        Integer offset = 0;
        Integer limit = 100000;

        TableVO tableVO = new TableVO();
        // 设置表头
        TableAssembler.buildColumns(tableVO,metaHolder.listMeta("dealer_detail_with_star_sign").values());
        tableVO.addColumn(null,ColumnVO.of("id_code","用户id",false))
                .addColumn("level_hk_at",ColumnVO.of("star_level_desc","服务商等级",false))
                .addColumn("bl_zone_name",ColumnVO.of("invite_star_level_desc","邀请星级等级",false))
                .addColumn("invite_star_level_desc",ColumnVO.of("sign_step_desc","签约状态",false));

        // 签约中状态
        List<Integer> signStepList = List.of(
                ReportMonthSignStepEnum.SEND_ALREADY,
                ReportMonthSignStepEnum.SURVEY_ALREADY,
                ReportMonthSignStepEnum.ACCOUNT_ALREADY,
                ReportMonthSignStepEnum.AUDIT_ALREADY,
                ReportMonthSignStepEnum.EXAM_ALREADY
        ).stream().map(ReportMonthSignStepEnum::getStep).collect(Collectors.toList());

        // KA下属secIdCode
        if (CollectionUtils.isEmpty(genSecIdCodes)) {
            return tableVO;
        }
        List<Long> secIdCodeList = genSecIdCodes.stream()
                .filter(Objects::nonNull)
                .map(UserIdCode::getValue).collect(Collectors.toList());

        List<Row> rowList =
                reportDealerInfoRepository.getStarSigningDealers(secIdCodeList,signStepList,offset,limit);

        if (CollectionUtils.isEmpty(rowList)) {
            return tableVO;
        }

        // 用户、用户上级
        List<String> keyList = List.of(
                "id_code",
                "sup_id_code"
        );

        Map<Long, UserInfo> userInfoMap = this.getUserInfosToMap(rowList,keyList);

        // 设置行数据
        TableAssembler.buildData(
                tableVO,
                rowList,
                metaHolder.listMeta("dealer_detail_with_star_sign").values(),
                List.of("id_code","star_level","sign_step","invite_star_level"));

        tableVO.resolveRow((data) -> {
            //转换星级等级描述
            int level = CastUtil.castInt(data.get("star_level"));
            StarLevelEnum starLevelEnum = StarLevelEnum.parseByCode(level);
            data.put("star_level_desc",starLevelEnum.getDesc());

            //转换邀请等级转换
            int inviteStarLevel = CastUtil.castInt(data.get("invite_star_level"));
            StarLevelEnum inviteStarLevelEnum = StarLevelEnum.parseByCode(inviteStarLevel);
            data.put("invite_star_level_desc",inviteStarLevelEnum.getDesc());

            //转换签约状态
            int signStepVal = CastUtil.castInt(data.get("sign_step"));
            StarSignStepEnum signStepEnum = StarSignStepEnum.getByStep(signStepVal);
            data.put("sign_step_desc",signStepEnum.getDesc());

            //昵称
            String nickName = CastUtil.castString(data.get("nick_name"));
            long idCode = CastUtil.castLong(data.get("id_code"));
            UserInfo userInfo = userInfoMap.get(idCode);
            if (StringUtils.isBlank(nickName) && userInfo != null) {
                data.put("nick_name",userInfo.getBackNickName());
            }

            // 上级昵称
            String supNickName = CastUtil.castString(data.get("sup_nick_name"));
            long supIdCode = CastUtil.castLong(data.get("sup_id_code"));
            UserInfo supUserInfo = userInfoMap.get(supIdCode);
            if (StringUtils.isBlank(supNickName) && supUserInfo != null) {
                data.put("sup_nick_name",supUserInfo.getBackNickName());
            }


        });

        return tableVO;
    }

    /**
     * 即将晋升服务商
     */
    public TableVO getTargetStarDealers(List<UserIdCode> genSecIdCodes) {
        Integer offset = 0;
        Integer limit = 100000;

        TableVO tableVO = new TableVO();

        // 设置表头
        TableAssembler.buildColumns(tableVO,metaHolder.listMeta("dealer_detail_with_target_star").values());
        tableVO.addColumn(null,ColumnVO.of("id_code","用户id",false))
                .addColumn("level_hk_at",ColumnVO.of("star_level_desc","服务商等级",false))
                .addColumn("last_login_time",ColumnVO.of("target_star_level_desc","即将晋升等级",false));

        if (CollectionUtils.isEmpty(genSecIdCodes)) {
            return tableVO;
        }
        List<Long> secIdCodeList = genSecIdCodes.stream()
                .map(UserIdCode::getValue).collect(Collectors.toList());

        List<Row> rowList =
                reportDealerInfoRepository.getNotNoneStarDealers(secIdCodeList,offset,limit);

        if (CollectionUtils.isEmpty(rowList)) {
            return tableVO;
        }

        // 用户、用户上级
        List<String> keyList = List.of(
                "id_code",
                "sup_id_code"
        );
        Map<Long, UserInfo> userInfoMap = this.getUserInfosToMap(rowList,keyList);


        // 设置行数据
        TableAssembler.buildData(
                tableVO,
                rowList,
                metaHolder.listMeta("dealer_detail_with_target_star").values(),
                List.of("id_code","star_level","target_star_level"));

        tableVO.resolveRow((data) -> {
            //转换星级等级描述
            int level = CastUtil.castInt(data.get("star_level"));
            StarLevelEnum starLevelEnum = StarLevelEnum.parseByCode(level);
            data.put("star_level_desc",starLevelEnum.getDesc());

            //昵称
            String nickName = CastUtil.castString(data.get("nick_name"));
            long idCode = CastUtil.castLong(data.get("id_code"));
            UserInfo userInfo = userInfoMap.get(idCode);
            if (StringUtils.isBlank(nickName) && userInfo != null) {
                data.put("nick_name",userInfo.getBackNickName());
            }

            // 上级昵称
            String supNickName = CastUtil.castString(data.get("sup_nick_name"));
            long supIdCode = CastUtil.castLong(data.get("sup_id_code"));
            UserInfo supUserInfo = userInfoMap.get(supIdCode);
            if (StringUtils.isBlank(supNickName) && supUserInfo != null) {
                data.put("sup_nick_name",supUserInfo.getBackNickName());
            }

            // 即将晋升等级转换
            int targetLevel = CastUtil.castInt(data.get("target_star_level"));
            StarLevelEnum targetLevelEnum = StarLevelEnum.parseByCode(targetLevel);
            data.put("target_star_level_desc",targetLevelEnum.getDesc());


        });

        return tableVO;
    }

    /**
     * 数据下载-服务商名单
     */
    public TableVO getDominationStarMember(Long idCode,Integer month) {
        Integer offset = 0;
        Integer limit = 100000;

        List<Row> rowList =
                reportDealerInfoRepository.getDominationStarMember(idCode,month,offset,limit);

        // 用户、用户上级
        List<String> keyList = List.of(
                "id_code",
                "sup_id_code"
        );
        Map<Long, UserInfo> userInfoMap = this.getUserInfosToMap(rowList,keyList);

        TableVO tableVO = new TableVO();
        // 设置表头
        TableAssembler.buildColumns(tableVO,metaHolder.listMeta("month_report_domination_star_member").values());
        tableVO.addColumn(null,ColumnVO.of("id_code","用户id",false))
                .addColumn("level_hk_at",ColumnVO.of("star_level_desc","服务商等级",false))
                .addColumn("bl_ka_leader_name",ColumnVO.of("target_star_level_desc","即将晋升等级",false))
                .addColumn("target_star_level_desc",ColumnVO.of("sign_step_desc","签约状态",false));

        // 设置行数据
        TableAssembler.buildData(
                tableVO,
                rowList,
                metaHolder.listMeta("month_report_domination_star_member").values(),
                List.of("id_code","star_level","target_star_level","sign_step"));

        tableVO.resolveRow((data) -> {
            //转换星级等级描述
            int level = CastUtil.castInt(data.get("star_level"));
            StarLevelEnum starLevelEnum = StarLevelEnum.parseByCode(level);
            if (starLevelEnum != null) {
                data.put("star_level_desc",starLevelEnum.getDesc());
            }

            //昵称
            String nickName = CastUtil.castString(data.get("nick_name"));
            long userIdCode = CastUtil.castLong(data.get("id_code"));
            UserInfo userInfo = userInfoMap.get(userIdCode);
            if (StringUtils.isBlank(nickName) && userInfo != null) {
                data.put("nick_name",userInfo.getBackNickName());
            }

            //转换签约状态
            int signStepVal = CastUtil.castInt(data.get("sign_step"));
            StarSignStepEnum signStepEnum = StarSignStepEnum.getByStep(signStepVal);
            if (signStepEnum != null) {
                data.put("sign_step_desc",signStepEnum.getDesc());
            }

            // 上级昵称
            String supNickName = CastUtil.castString(data.get("sup_nick_name"));
            long supIdCode = CastUtil.castLong(data.get("sup_id_code"));
            UserInfo supUserInfo = userInfoMap.get(supIdCode);
            if (StringUtils.isBlank(supNickName) && supUserInfo != null) {
                data.put("sup_nick_name",supUserInfo.getBackNickName());
            }

            // 即将晋升等级转换
            int targetLevel = CastUtil.castInt(data.get("target_star_level"));
            StarLevelEnum targetLevelEnum = StarLevelEnum.parseByCode(targetLevel);
            if (targetLevelEnum != null && !StarLevelEnum.NONE.equals(targetLevelEnum)) {
                data.put("target_star_level_desc",targetLevelEnum.getDesc());
            }

        });

        return tableVO;
    }




    /**
     * 获取用户信息
     */
    private Map<Long,UserInfo> getUserInfosToMap(List<Row> rowList,List<String> keyList) {
        if (CollectionUtils.isEmpty(rowList)) {
            return Maps.newHashMap();
        }
        if (CollectionUtils.isEmpty(keyList)) {
            return Maps.newHashMap();
        }

        List<Long> idCodeList = Lists.newArrayList();
        rowList.forEach(row -> keyList.forEach(key -> idCodeList.add(CastUtil.castLong(row.getValue(key)))));

        List<UserIdCode> userIdCodeList= idCodeList.stream()
                .filter(v -> v > 0L)
                .map(UserIdCode::new)
                .distinct()
                .collect(Collectors.toList());
        List<UserInfo> userInfos = userInfoRepository.batchGetUserInfo(userIdCodeList);

        return userInfos.stream()
                .collect(Collectors.toMap(k -> k.getIdCode().getValue(), v -> v, (v1, v2) -> v1));
    }




}
